﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BHan.Context
{
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 批量注册指定程序集中的所有实现了接口的类到 ServiceCollection
        /// </summary>
        /// <param name="services">ServiceCollection 实例</param>
        /// <param name="assembly">要扫描的程序集</param>
        public static IServiceCollection RegisterServicesFromAssembly(this IServiceCollection services, Assembly assembly)
        { 
          
            var types = assembly.GetTypes()
                .Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Any()); // 筛选出实现接口的类
            foreach (var type in types)
            {
                if(type.Name.Contains("Repository")) {

                    var serviceInterface = type.GetInterfaces().Where(t=>t.Name.Contains("Repository")).FirstOrDefault();
                    if (serviceInterface != null && !type.Name.Contains("Service"))
                    {
                        services.AddSingleton(serviceInterface, type); // 程序生命周期内只创建一个服务实例
                    }
                }
                if (type.Name.Contains("Window"))
                {
                    services.AddTransient(type);  // Transient（瞬时）：每次请求服务时，都会创建一个新的服务实例
                }
                if (type.Name.Contains("Page"))
                {
                    services.AddTransient(type);
                }
                if (type.Name.Contains("VM"))
                {
                    services.AddSingleton(type);
                }
                 
            }

            // 添加 Func<string, object> 工厂方法
            services.AddSingleton<Func<string, object>>(provider =>
            {
                // 构建工厂方法：根据名称获取实例
                return name =>
                {
                    // 根据已注册的服务类型动态解析
                    var registeredService = types.FirstOrDefault(t => t.Name == name);
                    if (registeredService != null)
                    {
                        return provider.GetService(registeredService);
                    }
                    // 未找到服务时抛出异常
                    throw new KeyNotFoundException($"No service registered with name '{name}'.");
                };
            });

            return services;
        }
         
    }
}
